namespace pengpeng {
	export class TextureParser {
		
		protected static NAME: string = "name";
		protected static TEXTURE_ATLAS: string = "TextureAtlas";
        protected static SUB_TEXTURE: string = "SubTexture";
        protected static FORMAT: string = "format";
        protected static IMAGE_PATH: string = "imagePath";
        protected static WIDTH: string = "width";
        protected static HEIGHT: string = "height";
        protected static ROTATED: string = "rotated";
        protected static FRAME_X: string = "frameX";
        protected static FRAME_Y: string = "frameY";
        protected static FRAME_WIDTH: string = "frameWidth";
        protected static FRAME_HEIGHT: string = "frameHeight";
        protected static SCALE: string = "scale";
        protected static X: string = "x";
        protected static Y: string = "y";

		
		public constructor() {
		}

		protected static _getBoolean(rawData: any, key: string, defaultValue: boolean): boolean {
            if (key in rawData) {
                const value = rawData[key];
                const valueType = typeof value;
                if (valueType === "boolean") {
                    return value;
                }
                else if (valueType === "string") {
                    switch (value) {
                        case "0":
                        case "NaN":
                        case "":
                        case "false":
                        case "null":
                        case "undefined":
                            return false;

                        default:
                            return true;
                    }
                }
                else {
                    return !!value;
                }
            }

            return defaultValue;
        }
        /**
         * @private
         */
        protected static _getNumber(rawData: any, key: string, defaultValue: number): number {
            if (key in rawData) {
                const value = rawData[key];
                if (value == null || value === "NaN") {
                    return defaultValue;
                }

                return +value || 0;
            }

            return defaultValue;
        }
        /**
         * @private
         */
        protected static _getString(rawData: any, key: string, defaultValue: string): string {
            if (key in rawData) {
                return String(rawData[key]);
            }

            return defaultValue;
        }

		public parseTextureAtlasData(rawData: any, textureAtlasData: TextureAtlasData, scale: number = 1.0): void 
		{
            if (rawData) {
                textureAtlasData.name = TextureParser._getString(rawData, TextureParser.NAME, null);
                textureAtlasData.imagePath = TextureParser._getString(rawData, TextureParser.IMAGE_PATH, null);
                textureAtlasData.width = TextureParser._getNumber(rawData, TextureParser.WIDTH, 0.0);
                textureAtlasData.height = TextureParser._getNumber(rawData, TextureParser.HEIGHT, 0.0);

                // Texture format.

                if (scale > 0.0) { // Use params scale.
                    textureAtlasData.scale = scale;
                }
                else { // Use data scale.
                    scale = textureAtlasData.scale = TextureParser._getNumber(rawData, TextureParser.SCALE, textureAtlasData.scale);
                }

                scale = 1.0 / scale;

                if ("SubTexture" in rawData) {
                    const rawTextures = rawData["SubTexture"] as Array<any>;
                    for (let i = 0, l = rawTextures.length; i < l; ++i) {
                        const rawTexture = rawTextures[i];
                        const textureData = textureAtlasData.generateTexture();
                        textureData.name = TextureParser._getString(rawTexture, TextureParser.NAME, null);
                        textureData.rotated = TextureParser._getBoolean(rawTexture, TextureParser.ROTATED, false);
                        textureData.region.x = TextureParser._getNumber(rawTexture, TextureParser.X, 0.0) * scale;
                        textureData.region.y = TextureParser._getNumber(rawTexture, TextureParser.Y, 0.0) * scale;
                        textureData.region.width = TextureParser._getNumber(rawTexture, TextureParser.WIDTH, 0.0) * scale;
                        textureData.region.height = TextureParser._getNumber(rawTexture, TextureParser.HEIGHT, 0.0) * scale;

                        const frameWidth = TextureParser._getNumber(rawTexture, TextureParser.FRAME_WIDTH, -1.0);
                        const frameHeight = TextureParser._getNumber(rawTexture, TextureParser.FRAME_HEIGHT, -1.0);
                        if (frameWidth > 0.0 && frameHeight > 0.0) {
                            textureData.frame = TextureData.generateRectangle();
                            textureData.frame.x = TextureParser._getNumber(rawTexture, TextureParser.FRAME_X, 0.0) * scale;
                            textureData.frame.y = TextureParser._getNumber(rawTexture, TextureParser.FRAME_Y, 0.0) * scale;
                            textureData.frame.width = frameWidth * scale;
                            textureData.frame.height = frameHeight * scale;
                        }

                        textureAtlasData.addTexture(textureData);
                    }
                }
            }
            else {
                throw new Error();
            }
        }
	}
}